// 版权所有2009 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// 包解析器为Go源文件实现一个解析器。输入可以是
// 以各种形式提供（参见各种Parse*函数）；
// 输出是代表Go源的抽象语法树（AST）。
// 解析器是通过Parse*函数之一调用的。
// 
// 语法分析器接受的语言比Go规范中语法允许的语言更大，这是为了简单，以及在出现语法错误时提高健壮性。例如，在方法声明中，接收方
// 被视为普通参数列表，因此可能包含多个
// 条目，而规范只允许一个条目。因此，AST（AST.FuncDecl.Recv）字段中对应的
// 字段不限于一个条目。
// 
package parser

import (
	"fmt"
	"go/ast"
	"go/internal/typeparams"
	"go/scanner"
	"go/token"
	"strconv"
	"strings"
	"unicode"
)

// 解析器结构保存解析器的内部状态。
type parser struct {
	file    *token.File
	errors  scanner.ErrorList
	scanner scanner.Scanner

	// 跟踪/调试
	mode   Mode // 解析模式
	trace  bool // /=（模式和跟踪！=0）
	indent int  // 用于跟踪输出的缩进

	// 注释
	comments    []*ast.CommentGroup
	leadComment *ast.CommentGroup // 最后一条线索注释
	lineComment *ast.CommentGroup // 最后一行注释

	// 下一个令牌
	pos token.Pos   // 令牌位置
	tok token.Token // 一个令牌展望
	lit string      // 令牌文字

	// 错误恢复
	// （用于限制对解析器的调用数量。advance 
	// w/o正在进行扫描-避免在错误恢复期间在多个解析器函数之间可能出现无休止的
	// 循环）
	syncPos token.Pos // 最后一次同步位置
	syncCnt int       // 解析器数量。advance calls without progress 

	// 非语法分析器控制
	exprLev int  // <0:在控制子句中，>=0:在表达式中
	inRhs   bool // 如果设置，解析程序正在解析rhs表达式

	imports []*ast.ImportSpec // 导入列表
}

func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mode) {
	p.file = fset.AddFile(filename, -1, len(src))
	var m scanner.Mode
	if mode&ParseComments != 0 {
		m = scanner.ScanComments
	}
	eh := func(pos token.Position, msg string) { p.errors.Add(pos, msg) }
	p.scanner.Init(p.file, src, eh, m)

	p.mode = mode
	p.trace = mode&Trace != 0 // 为方便起见（经常使用p.trace）
	p.next()
}

func (p *parser) allowGenerics() bool { return p.mode&typeparams.DisallowParsing == 0 }
func (p *parser) allowTypeSets() bool { return p.mode&typeparams.DisallowTypeSets == 0 }

// ---------------------------------------------------------------
// 解析支持

func (p *parser) printTrace(a ...any) {
	const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
	const n = len(dots)
	pos := p.file.Position(p.pos)
	fmt.Printf("%5d:%3d: ", pos.Line, pos.Column)
	i := 2 * p.indent
	for i > n {
		fmt.Print(dots)
		i -= n
	}
	// /i<=n 
	fmt.Print(dots[0:i])
	fmt.Println(a...)
}

func trace(p *parser, msg string) *parser {
	p.printTrace(msg, "(")
	p.indent++
	return p
}

// 使用模式：延迟un（trace（p，“…”）
func un(p *parser) {
	p.indent--
	p.printTrace(")")
}

// 前进到下一个令牌。
func (p *parser) next0() {
	// 由于有一个令牌是向前看的，所以在跟踪时打印上一个令牌
	// 因为它提供了更可读的输出。
	// 第一个令牌（！p.pos.IsValid（））没有初始化
	// （它是token.unliked），所以不要打印它。
	if p.trace && p.pos.IsValid() {
		s := p.tok.String()
		switch {
		case p.tok.IsLiteral():
			p.printTrace(s, p.lit)
		case p.tok.IsOperator(), p.tok.IsKeyword():
			p.printTrace("\"" + s + "\"")
		default:
			p.printTrace(s)
		}
	}

	p.pos, p.tok, p.lit = p.scanner.Scan()
}

// 使用一条评论并返回它和它结束的那一行。
func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
	// *-风格的评论可能会以不同的行结束，而不是从哪里开始。
	// 扫描注释中的“\n”字符，并相应地调整结束行。
	endline = p.file.Line(p.pos)
	if p.lit[1] == '*' {
		// 此处不使用range-无需解码Unicode代码点
		for i := 0; i < len(p.lit); i++ {
			if p.lit[i] == '\n' {
				endline++
			}
		}
	}

	comment = &ast.Comment{Slash: p.pos, Text: p.lit}
	p.next0()

	return
}

// 使用一组相邻的注释，将其添加到解析器的
// 注释列表中，并将其与组中最后一条注释结束的行一起返回。非注释标记或n 
// 空行终止注释组。
// 
func (p *parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) {
	var list []*ast.Comment
	endline = p.file.Line(p.pos)
	for p.tok == token.COMMENT && p.file.Line(p.pos) <= endline+n {
		var comment *ast.Comment
		comment, endline = p.consumeComment()
		list = append(list, comment)
	}

	// 将注释组添加到注释列表
	comments = &ast.CommentGroup{List: list}
	p.comments = append(p.comments, comments)

	return
}

// 前进到下一个非注释标记。在此过程中，收集
// 遇到的任何评论组，并记住最后一条线索和
// 行评论。
// 
// 引导注释是一个注释组，以
// 行开始和结束，不带任何其他标记，紧接着是注释组后面的一行上的非注释
// 标记。
// 
// 行注释是在同一行上跟随非注释
// 标记的注释组，并且在其结束的行
// 上没有标记。
// 
// 前置和行注释可能被视为存储在AST中的
// 文档。
// 
func (p *parser) next() {
	p.leadComment = nil
	p.lineComment = nil
	prev := p.pos
	p.next0()

	if p.tok == token.COMMENT {
		var comment *ast.CommentGroup
		var endline int

		if p.file.Line(p.pos) == p.file.Line(prev) {
			// 注释与上一个标记位于同一行；它
			// 不能是引导注释，但可以是行注释。
			comment, endline = p.consumeCommentGroup(0)
			if p.file.Line(p.pos) != endline || p.tok == token.EOF {
				// 下一个标记位于另一行，因此
				// 最后一个注释组是行注释。
				p.lineComment = comment
			}
		}

		// 使用后续注释，如果有任何
		endline = -1
		for p.tok == token.COMMENT {
			comment, endline = p.consumeCommentGroup(1)
		}

		if endline+1 == p.file.Line(p.pos) {
			// 下一个标记紧跟在
			// 注释组之后，因此最后一个注释组是引导注释。
			p.leadComment = comment
		}
	}
}

// 出现紧急救援恐慌，表明提前终止。
type bailout struct{}

func (p *parser) error(pos token.Pos, msg string) {
	if p.trace {
		defer un(trace(p, "error: "+msg))
	}

	epos := p.file.Position(pos)

	// 如果未设置AllErrors，则放弃在同一行
	// 上报告的错误作为最后记录的错误，如果存在超过
	// 10个错误，则停止解析。
	if p.mode&AllErrors == 0 {
		n := len(p.errors)
		if n > 0 && p.errors[n-1].Pos.Line == epos.Line {
			return // 放弃-可能是一个虚假错误
		}
		if n > 10 {
			panic(bailout{})
		}
	}

	p.errors.Add(epos, msg)
}

func (p *parser) errorExpected(pos token.Pos, msg string) {
	msg = "expected " + msg
	if pos == p.pos {
		// 错误发生在当前位置；
		// 使错误消息更具体
		switch {
		case p.tok == token.SEMICOLON && p.lit == "\n":
			msg += ", found newline"
		case p.tok.IsLiteral():
			// 打印123而不是“INT”，等等。
			msg += ", found " + p.lit
		default:
			msg += ", found '" + p.tok.String() + "'"
		}
	}
	p.error(pos, msg)
}

func (p *parser) expect(tok token.Token) token.Pos {
	pos := p.pos
	if p.tok != tok {
		p.errorExpected(pos, "'"+tok.String()+"'")
	}
	p.next() // 取得进展
	return pos
}

// expect2与expect类似，但如果找不到所需的令牌，它将返回一个无效位置
// 。
func (p *parser) expect2(tok token.Token) (pos token.Pos) {
	if p.tok == tok {
		pos = p.pos
	} else {
		p.errorExpected(p.pos, "'"+tok.String()+"'")
	}
	p.next() // 取得进展
	return
}

// expectClosing与expect类似，但提供了更好的错误消息
// 用于换行符前缺少逗号的常见情况。
// 
func (p *parser) expectClosing(tok token.Token, context string) token.Pos {
	if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" {
		p.error(p.pos, "missing ',' before newline in "+context)
		p.next()
	}
	return p.expect(tok)
}

func (p *parser) expectSemi() {
	// 在结束之前分号是可选的“'）或“}”
	if p.tok != token.RPAREN && p.tok != token.RBRACE {
		switch p.tok {
		case token.COMMA:
			// 允许使用“，”而不是“；”但投诉
			p.errorExpected(p.pos, "';'")
			fallthrough
		case token.SEMICOLON:
			p.next()
		default:
			p.errorExpected(p.pos, "';'")
			p.advance(stmtStart)
		}
	}
}

func (p *parser) atComma(context string, follow token.Token) bool {
	if p.tok == token.COMMA {
		return true
	}
	if p.tok != follow {
		msg := "missing ','"
		if p.tok == token.SEMICOLON && p.lit == "\n" {
			msg += " before newline"
		}
		p.error(p.pos, msg+" in "+context)
		return true // “插入”逗号，并继续
	}
	return false
}

func assert(cond bool, msg string) {
	if !cond {
		panic("go/parser internal error: " + msg)
	}
}

// advance使用代币，直到当前代币p.tok 
// 位于“to”集合或代币中。EOF。用于错误恢复。
func (p *parser) advance(to map[token.Token]bool) {
	for ; p.tok != token.EOF; p.next() {
		if to[p.tok] {
			// 仅当解析器自上次
			// 同步以来取得了一些进展，或者在没有
			// 进展的情况下未达到10次提前调用时返回。否则，使用至少一个令牌来避免无休止的解析器循环（可能是因为parseOperator和parseStmt调用advance和
			// 不能正确地前进，因此需要使用
			// 调用限制p.syncnt）。
			if p.pos == p.syncPos && p.syncCnt < 10 {
				p.syncCnt++
				return
			}
			if p.pos > p.syncPos {
				p.syncPos = p.pos
				p.syncCnt = 0
				return
			}
			// 到达此处表示存在语法错误，可能是
			// 此函数中的令牌列表不正确，但只有
			// 在出现之前的错误时，才会导致跳过可能正确的代码，因此与非终止语法相比，首选
			// 。
		}
	}
}

var stmtStart = map[token.Token]bool{
	token.BREAK:       true,
	token.CONST:       true,
	token.CONTINUE:    true,
	token.DEFER:       true,
	token.FALLTHROUGH: true,
	token.FOR:         true,
	token.GO:          true,
	token.GOTO:        true,
	token.IF:          true,
	token.RETURN:      true,
	token.SELECT:      true,
	token.SWITCH:      true,
	token.TYPE:        true,
	token.VAR:         true,
}

var declStart = map[token.Token]bool{
	token.CONST: true,
	token.TYPE:  true,
	token.VAR:   true,
}

var exprEnd = map[token.Token]bool{
	token.COMMA:     true,
	token.COLON:     true,
	token.SEMICOLON: true,
	token.RPAREN:    true,
	token.RBRACK:    true,
	token.RBRACE:    true,
}

// safePos返回给定位置的有效文件位置：如果pos 
// 开头有效，safePos返回pos。如果pos超出范围，
// safePos返回EOF位置。
// 
// 这是一个黑客程序，可以绕过AST中的“人工”结束位置，通过将1添加到（可能有效的）标记位置来计算
// 结束位置。如果
// 标记位置由于解析错误而无效，则生成的结束位置
// 可能超过了文件的EOF位置，如果以后使用
// 会导致恐慌。
// 
func (p *parser) safePos(pos token.Pos) (res token.Pos) {
	defer func() {
		if recover() != nil {
			res = token.Pos(p.file.Base() + p.file.Size()) // EOF position 
		}
	}()
	_ = p.file.Offset(pos) // 如果position超出范围，触发恐慌
	return pos
}

// -----------------------------------------------------------------------------------------------------------------
// 标识符

func (p *parser) parseIdent() *ast.Ident {
	pos := p.pos
	name := "_"
	if p.tok == token.IDENT {
		name = p.lit
		p.next()
	} else {
		p.expect(token.IDENT) // use expect（）错误处理
	}
	return &ast.Ident{NamePos: pos, Name: name}
}

func (p *parser) parseIdentList() (list []*ast.Ident) {
	if p.trace {
		defer un(trace(p, "IdentList"))
	}

	list = append(list, p.parseIdent())
	for p.tok == token.COMMA {
		p.next()
		list = append(list, p.parseIdent())
	}

	return
}

// ----------------------------------------------------------------------------------------------------------------
// 常见产品

// 如果设置了lhs，则不解析作为标识符的结果列表元素。
func (p *parser) parseExprList() (list []ast.Expr) {
	if p.trace {
		defer un(trace(p, "ExpressionList"))
	}

	list = append(list, p.checkExpr(p.parseExpr()))
	for p.tok == token.COMMA {
		p.next()
		list = append(list, p.checkExpr(p.parseExpr()))
	}

	return
}

func (p *parser) parseList(inRhs bool) []ast.Expr {
	old := p.inRhs
	p.inRhs = inRhs
	list := p.parseExprList()
	p.inRhs = old
	return list
}

// ---------------------------------------------------------------
// 类型

func (p *parser) parseType() ast.Expr {
	if p.trace {
		defer un(trace(p, "Type"))
	}

	typ := p.tryIdentOrType()

	if typ == nil {
		pos := p.pos
		p.errorExpected(pos, "type")
		p.advance(exprEnd)
		return &ast.BadExpr{From: pos, To: p.pos}
	}

	return typ
}

func (p *parser) parseQualifiedIdent(ident *ast.Ident) ast.Expr {
	if p.trace {
		defer un(trace(p, "QualifiedIdent"))
	}

	typ := p.parseTypeName(ident)
	if p.tok == token.LBRACK && p.allowGenerics() {
		typ = p.parseTypeInstance(typ)
	}

	return typ
}

// 如果结果是标识符，则不会解析。
func (p *parser) parseTypeName(ident *ast.Ident) ast.Expr {
	if p.trace {
		defer un(trace(p, "TypeName"))
	}

	if ident == nil {
		ident = p.parseIdent()
	}

	if p.tok == token.PERIOD {
		// ident是一个包名
		p.next()
		sel := p.parseIdent()
		return &ast.SelectorExpr{X: ident, Sel: sel}
	}

	return ident
}

// “[”已经被消耗，而lbrack是它的位置。
// 如果len！=nil它是已消耗的数组长度。
func (p *parser) parseArrayType(lbrack token.Pos, len ast.Expr) *ast.ArrayType {
	if p.trace {
		defer un(trace(p, "ArrayType"))
	}

	if len == nil {
		p.exprLev++
		// 始终允许省略以进行更容错的解析
		if p.tok == token.ELLIPSIS {
			len = &ast.Ellipsis{Ellipsis: p.pos}
			p.next()
		} else if p.tok != token.RBRACK {
			len = p.parseRhs()
		}
		p.exprLev--
	}
	if p.tok == token.COMMA {
		// 在类型参数
		// 列表中接受尾随逗号，但在数组类型声明中不接受尾随逗号。
		// 接受更好的错误处理，但抱怨。
		p.error(p.pos, "unexpected comma; expecting ]")
		p.next()
	}
	p.expect(token.RBRACK)
	elt := p.parseType()
	return &ast.ArrayType{Lbrack: lbrack, Len: len, Elt: elt}
}

func (p *parser) parseArrayFieldOrTypeInstance(x *ast.Ident) (*ast.Ident, ast.Expr) {
	if p.trace {
		defer un(trace(p, "ArrayFieldOrTypeInstance"))
	}

	// TODO（gri）我们应该在类型参数中允许一个尾随逗号吗？（我们在parseTypeInstance中是这样做的）。ABCFDG 
	lbrack := p.expect(token.LBRACK)
	var args []ast.Expr
	var firstComma token.Pos
	argparser := p.parseRhsOrType
	if !p.allowGenerics() {
		argparser = p.parseRhs
	}
	if p.tok != token.RBRACK {
		p.exprLev++
		args = append(args, argparser())
		for p.tok == token.COMMA {
			if !firstComma.IsValid() {
				firstComma = p.pos
			}
			p.next()
			args = append(args, argparser())
		}
		p.exprLev--
	}
	rbrack := p.expect(token.RBRACK)

	if len(args) == 0 {
		// x[]E 
		elt := p.parseType()
		return x, &ast.ArrayType{Lbrack: lbrack, Elt: elt}
	}

	// x[P]E或x[P]
	if len(args) == 1 {
		elt := p.tryIdentOrType()
		if elt != nil {
			// x[P]E 
			return x, &ast.ArrayType{Lbrack: lbrack, Len: args[0], Elt: elt}
		}
		if !p.allowGenerics() {
			p.error(rbrack, "missing element type in array type expression")
			return nil, &ast.BadExpr{From: args[0].Pos(), To: args[0].End()}
		}
	}

	if !p.allowGenerics() {
		p.error(firstComma, "expected ']', found ','")
		return x, &ast.BadExpr{From: args[0].Pos(), To: args[len(args)-1].End()}
	}

	// x[P]，x[P1，P2]。。。
	return nil, typeparams.PackIndexExpr(x, lbrack, args, rbrack)
}

func (p *parser) parseFieldDecl() *ast.Field {
	if p.trace {
		defer un(trace(p, "FieldDecl"))
	}

	doc := p.leadComment

	var names []*ast.Ident
	var typ ast.Expr
	if p.tok == token.IDENT {
		name := p.parseIdent()
		if p.tok == token.PERIOD || p.tok == token.STRING || p.tok == token.SEMICOLON || p.tok == token.RBRACE {
			// 嵌入式类型
			typ = name
			if p.tok == token.PERIOD {
				typ = p.parseQualifiedIdent(name)
			}
		} else {
			// 名称1，名称2。。。T 
			names = []*ast.Ident{name}
			for p.tok == token.COMMA {
				p.next()
				names = append(names, p.parseIdent())
			}
			// 小心跳舞：我们不知道是否有嵌入式实例化的
			// 键入T[P1，P2，…]或数组类型为[E]或[P]E.
			if len(names) == 1 && p.tok == token.LBRACK {
				name, typ = p.parseArrayFieldOrTypeInstance(name)
				if name == nil {
					names = nil
				}
			} else {
				// T P 
				typ = p.parseType()
			}
		}
	} else {
		// embedded的字段T，可能是泛型类型
		// （使用圆括号将其与命名字段声明区分开来）
		// TODO（rFindley）确认这不允许在访问p.linecomment 
		typ = p.parseType()
	}

	var tag *ast.BasicLit
	if p.tok == token.STRING {
		tag = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
		p.next()
	}


	field := &ast.Field{Doc: doc, Names: names, Type: typ, Tag: tag, Comment: p.lineComment}
	return field
}

func (p *parser) parseStructType() *ast.StructType {
	if p.trace {
		defer un(trace(p, "StructType"))
	}

	pos := p.expect(token.STRUCT)
	lbrace := p.expect(token.LBRACE)
	var list []*ast.Field
	for p.tok == token.IDENT || p.tok == token.MUL || p.tok == token.LPAREN {
		// 字段声明不能以（'但是我们接受
		// 这里使用它是为了更健壮的解析和更好的错误消息
		// （如有必要，parseFieldDecl将检查并投诉）
		list = append(list, p.parseFieldDecl())
	}
	rbrace := p.expect(token.RBRACE)

	return &ast.StructType{
		Struct: pos,
		Fields: &ast.FieldList{
			Opening: lbrace,
			List:    list,
			Closing: rbrace,
		},
	}
}

func (p *parser) parsePointerType() *ast.StarExpr {
	if p.trace {
		defer un(trace(p, "PointerType"))
	}

	star := p.expect(token.MUL)
	base := p.parseType()

	return &ast.StarExpr{Star: star, X: base}
}

func (p *parser) parseDotsType() *ast.Ellipsis {
	if p.trace {
		defer un(trace(p, "DotsType"))
	}

	pos := p.expect(token.ELLIPSIS)
	elt := p.parseType()

	return &ast.Ellipsis{Ellipsis: pos, Elt: elt}
}

type field struct {
	name *ast.Ident
	typ  ast.Expr
}

func (p *parser) parseParamDecl(name *ast.Ident, typeSetsOK bool) (f field) {
	// TODO（rFindley）重构，使其在语法上更类似于paramDeclOrNil 
	// package 
	if p.trace {
		defer un(trace(p, "ParamDeclOrNil"))
	}

	ptok := p.tok
	if name != nil {
		p.tok = token.IDENT // force token。
	} else if typeSetsOK && p.tok == token.TILDE {
		// /“~”下方开关中的识别码。。。
		return field{nil, p.embeddedElem(nil)}
	}

	switch p.tok {
	case token.IDENT:
		// 名称
		if name != nil {
			f.name = name
			p.tok = ptok
		} else {
			f.name = p.parseIdent()
		}
		switch p.tok {
		case token.IDENT, token.MUL, token.ARROW, token.FUNC, token.CHAN, token.MAP, token.STRUCT, token.INTERFACE, token.LPAREN:
			// 名称类型
			f.typ = p.parseType()

		case token.LBRACK:
			// 名称“[“type1，…，typeN”]”或名称“[“n”]”类型
			f.name, f.typ = p.parseArrayFieldOrTypeInstance(f.name)

		case token.ELLIPSIS:
			// 名称“…”键入
			f.typ = p.parseDotsType()
			return // 不允许。。。键入“|”。。。

		case token.PERIOD:
			// 名称“。。。
			f.typ = p.parseQualifiedIdent(f.name)
			f.name = nil

		case token.TILDE:
			if typeSetsOK {
				f.typ = p.embeddedElem(nil)
				return
			}

		case token.OR:
			if typeSetsOK {
				// name“|”排版
				f.typ = p.embeddedElem(f.name)
				f.name = nil
				return
			}
		}

	case token.MUL, token.ARROW, token.FUNC, token.LBRACK, token.CHAN, token.MAP, token.STRUCT, token.INTERFACE, token.LPAREN:
		// type 
		f.typ = p.parseType()

	case token.ELLIPSIS:
		// ”输入
		// （始终接受）
		f.typ = p.parseDotsType()
		return // 不允许。。。键入“|”。。。

	default:
		// TODO（rfindley）：对于类型参数
		// lists，这看起来不正确。
		p.errorExpected(p.pos, ")")
		p.advance(exprEnd)
	}

	// /[name]type“|”
	if typeSetsOK && p.tok == token.OR && f.typ != nil {
		f.typ = p.embeddedElem(f.typ)
	}

	return
}

func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing token.Token) (params []*ast.Field) {
	if p.trace {
		defer un(trace(p, "ParameterList"))
	}

	// type参数是唯一以“]”结尾的参数列表。
	tparams := closing == token.RBRACK
	// 类型参数列表中的类型集表示法是正确的。
	typeSetsOK := tparams && p.allowTypeSets()

	pos := p.pos
	if name0 != nil {
		pos = name0.Pos()
	}

	var list []field
	var named int // 具有显式名称和类型的参数数

	for name0 != nil || p.tok != closing && p.tok != token.EOF {
		var par field
		if typ0 != nil {
			if typeSetsOK {
				typ0 = p.embeddedElem(typ0)
			}
			par = field{name0, typ0}
		} else {
			par = p.parseParamDecl(name0, typeSetsOK)
		}
		name0 = nil // 如果当前
		typ0 = nil  // 如果当前
		if par.name != nil || par.typ != nil {
			list = append(list, par)
			if par.name != nil && par.typ != nil {
				named++
			}
		}
		if !p.atComma("parameter list", closing) {
			break
		}
		p.next()
	}

	if len(list) == 0 {
		return // 则使用第一个类型的参数分配并转换为[]*ast。字段ABCFDG 
	}


	if named == 0 {
		for i := 0; i < len(list); i++ {
			par := &list[i]
			if typ := par.name; typ != nil {
				par.typ = typ
				par.name = nil
			}
		}
		if tparams {
			p.error(pos, "all type parameters must be named")
		}
	} else if named != len(list) {
		ok := true
		var typ ast.Expr
		missingName := pos
		for i := len(list) - 1; i >= 0; i-- {
			if par := &list[i]; par.typ != nil {
				typ = par.typ
				if par.name == nil {
					ok = false
					missingName = par.typ.Pos()
					n := ast.NewIdent("_")
					par.name = n
				}
			} else if typ != nil {
				par.typ = typ
			} else {
				ok = false
				missingName = par.name.Pos()
				par.typ = &ast.BadExpr{From: par.name.Pos(), To: p.pos}
			}
		}
		if !ok {
			if tparams {
				p.error(missingName, "all type parameters must be named")
			} else {
				p.error(pos, "mixed named and unnamed parameters")
			}
		}
	}

	// 转换列表[]*ast。字段
	if named == 0 {
		// 参数列表仅由类型组成
		for _, par := range list {
			assert(par.typ != nil, "nil type in unnamed parameter list")
			params = append(params, &ast.Field{Type: par.typ})
		}
		return
	}

	// 参数列表由命名参数组成，类型
	var names []*ast.Ident
	var typ ast.Expr
	addParams := func() {
		assert(typ != nil, "nil type in named parameter list")
		field := &ast.Field{Names: names, Type: typ}
		params = append(params, field)
		names = nil
	}
	for _, par := range list {
		if par.typ != typ {
			if len(names) > 0 {
				addParams()
			}
			typ = par.typ
		}
		names = append(names, par.name)
	}
	if len(names) > 0 {
		addParams()
	}
	return
}

func (p *parser) parseParameters(acceptTParams bool) (tparams, params *ast.FieldList) {
	if p.trace {
		defer un(trace(p, "Parameters"))
	}

	if p.allowGenerics() && acceptTParams && p.tok == token.LBRACK {
		opening := p.pos
		p.next()
		// /[T any]（params）语法
		list := p.parseParameterList(nil, nil, token.RBRACK)
		rbrack := p.expect(token.RBRACK)
		tparams = &ast.FieldList{Opening: opening, List: list, Closing: rbrack}
		// 类型参数列表不能为空。
		if tparams.NumFields() == 0 {
			p.error(tparams.Closing, "empty type parameter list")
			tparams = nil // 避免后续错误
		}
	}

	opening := p.expect(token.LPAREN)

	var fields []*ast.Field
	if p.tok != token.RPAREN {
		fields = p.parseParameterList(nil, nil, token.RPAREN)
	}

	rparen := p.expect(token.RPAREN)
	params = &ast.FieldList{Opening: opening, List: fields, Closing: rparen}

	return
}

func (p *parser) parseResult() *ast.FieldList {
	if p.trace {
		defer un(trace(p, "Result"))
	}

	if p.tok == token.LPAREN {
		_, results := p.parseParameters(false)
		return results
	}

	typ := p.tryIdentOrType()
	if typ != nil {
		list := make([]*ast.Field, 1)
		list[0] = &ast.Field{Type: typ}
		return &ast.FieldList{List: list}
	}

	return nil
}

func (p *parser) parseFuncType() *ast.FuncType {
	if p.trace {
		defer un(trace(p, "FuncType"))
	}

	pos := p.expect(token.FUNC)
	tparams, params := p.parseParameters(true)
	if tparams != nil {
		p.error(tparams.Pos(), "function type must have no type parameters")
	}
	results := p.parseResult()

	return &ast.FuncType{Func: pos, Params: params, Results: results}
}

func (p *parser) parseMethodSpec() *ast.Field {
	if p.trace {
		defer un(trace(p, "MethodSpec"))
	}

	doc := p.leadComment
	var idents []*ast.Ident
	var typ ast.Expr
	x := p.parseTypeName(nil)
	if ident, _ := x.(*ast.Ident); ident != nil {
		switch {
		case p.tok == token.LBRACK && p.allowGenerics():
			// 泛型方法或嵌入的实例化类型
			lbrack := p.pos
			p.next()
			p.exprLev++
			x := p.parseExpr()
			p.exprLev--
			if name0, _ := x.(*ast.Ident); name0 != nil && p.tok != token.COMMA && p.tok != token.RBRACK {
				// 泛型方法m[T any]
				// 
				// 接口方法没有类型参数。我们将它们解析为
				// 更好的错误消息和更好的错误恢复。
				_ = p.parseParameterList(name0, nil, token.RBRACK)
				_ = p.expect(token.RBRACK)
				p.error(lbrack, "interface method must have no type parameters")

				// TODO（rfindley）重构以与parseFuncType共享代码。
				_, params := p.parseParameters(false)
				results := p.parseResult()
				idents = []*ast.Ident{ident}
				typ = &ast.FuncType{
					Func:    token.NoPos,
					Params:  params,
					Results: results,
				}
			} else {
				// 嵌入式实例化类型
				// TODO（rfindley）应解析x中的所有标识符。
				list := []ast.Expr{x}
				if p.atComma("type argument list", token.RBRACK) {
					p.exprLev++
					p.next()
					for p.tok != token.RBRACK && p.tok != token.EOF {
						list = append(list, p.parseType())
						if !p.atComma("type argument list", token.RBRACK) {
							break
						}
						p.next()
					}
					p.exprLev--
				}
				rbrack := p.expectClosing(token.RBRACK, "type argument list")
				typ = typeparams.PackIndexExpr(ident, lbrack, list, rbrack)
			}
		case p.tok == token.LPAREN:
			// 普通方法
			// TODO（rfindley）重构以与parseFuncType共享代码。
			_, params := p.parseParameters(false)
			results := p.parseResult()
			idents = []*ast.Ident{ident}
			typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
		default:
			// 嵌入式类型
			typ = x
		}
	} else {
		// 嵌入式，可能实例化类型
		typ = x
		if p.tok == token.LBRACK && p.allowGenerics() {
			// 嵌入式实例化接口
			typ = p.parseTypeInstance(typ)
		}
	}

	// 在调用站点添加注释：下面的字段可能与
	// 使用“|”的其他类型规范连接。
	// TODO（rfindley）这应该被重构。
	// TODO（rfindley）添加更多注释处理测试。
	return &ast.Field{Doc: doc, Names: idents, Type: typ}
}

func (p *parser) embeddedElem(x ast.Expr) ast.Expr {
	if p.trace {
		defer un(trace(p, "EmbeddedElem"))
	}
	if x == nil {
		x = p.embeddedTerm()
	}
	for p.tok == token.OR {
		t := new(ast.BinaryExpr)
		t.OpPos = p.pos
		t.Op = token.OR
		p.next()
		t.X = x
		t.Y = p.embeddedTerm()
		x = t
	}
	return x
}

func (p *parser) embeddedTerm() ast.Expr {
	if p.trace {
		defer un(trace(p, "EmbeddedTerm"))
	}
	if p.tok == token.TILDE {
		t := new(ast.UnaryExpr)
		t.OpPos = p.pos
		t.Op = token.TILDE
		p.next()
		t.X = p.parseType()
		return t
	}

	t := p.tryIdentOrType()
	if t == nil {
		pos := p.pos
		p.errorExpected(pos, "~ term or type")
		p.advance(exprEnd)
		return &ast.BadExpr{From: pos, To: p.pos}
	}

	return t
}

func (p *parser) parseInterfaceType() *ast.InterfaceType {
	if p.trace {
		defer un(trace(p, "InterfaceType"))
	}

	pos := p.expect(token.INTERFACE)
	lbrace := p.expect(token.LBRACE)

	var list []*ast.Field

parseElements:
	for {
		switch {
		case p.tok == token.IDENT:
			f := p.parseMethodSpec()
			if f.Names == nil && p.allowGenerics() {
				f.Type = p.embeddedElem(f.Type)
			}
			p.expectSemi()
			f.Comment = p.lineComment
			list = append(list, f)
		case p.tok == token.TILDE && p.allowGenerics():
			typ := p.embeddedElem(nil)
			p.expectSemi()
			comment := p.lineComment
			list = append(list, &ast.Field{Type: typ, Comment: comment})
		case p.allowGenerics():
			if t := p.tryIdentOrType(); t != nil {
				typ := p.embeddedElem(t)
				p.expectSemi()
				comment := p.lineComment
				list = append(list, &ast.Field{Type: typ, Comment: comment})
			} else {
				break parseElements
			}
		default:
			break parseElements
		}
	}

	// TODO（rfindley）：这里产生的错误可以改进，因为我们可以在此时接受标识符“type”或“}”。
	rbrace := p.expect(token.RBRACE)

	return &ast.InterfaceType{
		Interface: pos,
		Methods: &ast.FieldList{
			Opening: lbrace,
			List:    list,
			Closing: rbrace,
		},
	}
}

func (p *parser) parseMapType() *ast.MapType {
	if p.trace {
		defer un(trace(p, "MapType"))
	}

	pos := p.expect(token.MAP)
	p.expect(token.LBRACK)
	key := p.parseType()
	p.expect(token.RBRACK)
	value := p.parseType()

	return &ast.MapType{Map: pos, Key: key, Value: value}
}

func (p *parser) parseChanType() *ast.ChanType {
	if p.trace {
		defer un(trace(p, "ChanType"))
	}

	pos := p.pos
	dir := ast.SEND | ast.RECV
	var arrow token.Pos
	if p.tok == token.CHAN {
		p.next()
		if p.tok == token.ARROW {
			arrow = p.pos
			p.next()
			dir = ast.SEND
		}
	} else {
		arrow = p.expect(token.ARROW)
		p.expect(token.CHAN)
		dir = ast.RECV
	}
	value := p.parseType()

	return &ast.ChanType{Begin: pos, Arrow: arrow, Dir: dir, Value: value}
}

func (p *parser) parseTypeInstance(typ ast.Expr) ast.Expr {
	assert(p.allowGenerics(), "parseTypeInstance while not parsing type params")
	if p.trace {
		defer un(trace(p, "TypeInstance"))
	}

	opening := p.expect(token.LBRACK)
	p.exprLev++
	var list []ast.Expr
	for p.tok != token.RBRACK && p.tok != token.EOF {
		list = append(list, p.parseType())
		if !p.atComma("type argument list", token.RBRACK) {
			break
		}
		p.next()
	}
	p.exprLev--

	closing := p.expectClosing(token.RBRACK, "type argument list")

	if len(list) == 0 {
		p.errorExpected(closing, "type argument list")
		return &ast.IndexExpr{
			X:      typ,
			Lbrack: opening,
			Index:  &ast.BadExpr{From: opening + 1, To: closing},
			Rbrack: closing,
		}
	}

	return typeparams.PackIndexExpr(typ, opening, list, closing)
}

func (p *parser) tryIdentOrType() ast.Expr {
	switch p.tok {
	case token.IDENT:
		typ := p.parseTypeName(nil)
		if p.tok == token.LBRACK && p.allowGenerics() {
			typ = p.parseTypeInstance(typ)
		}
		return typ
	case token.LBRACK:
		lbrack := p.expect(token.LBRACK)
		return p.parseArrayType(lbrack, nil)
	case token.STRUCT:
		return p.parseStructType()
	case token.MUL:
		return p.parsePointerType()
	case token.FUNC:
		typ := p.parseFuncType()
		return typ
	case token.INTERFACE:
		return p.parseInterfaceType()
	case token.MAP:
		return p.parseMapType()
	case token.CHAN, token.ARROW:
		return p.parseChanType()
	case token.LPAREN:
		lparen := p.pos
		p.next()
		typ := p.parseType()
		rparen := p.expect(token.RPAREN)
		return &ast.ParenExpr{Lparen: lparen, X: typ, Rparen: rparen}
	}

	// 找不到类型
	return nil
}

// ----------------------------------------------------------------------------------------
// 块

func (p *parser) parseStmtList() (list []ast.Stmt) {
	if p.trace {
		defer un(trace(p, "StatementList"))
	}

	for p.tok != token.CASE && p.tok != token.DEFAULT && p.tok != token.RBRACE && p.tok != token.EOF {
		list = append(list, p.parseStmt())
	}

	return
}

func (p *parser) parseBody() *ast.BlockStmt {
	if p.trace {
		defer un(trace(p, "Body"))
	}

	lbrace := p.expect(token.LBRACE)
	list := p.parseStmtList()
	rbrace := p.expect2(token.RBRACE)

	return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
}

func (p *parser) parseBlockStmt() *ast.BlockStmt {
	if p.trace {
		defer un(trace(p, "BlockStmt"))
	}

	lbrace := p.expect(token.LBRACE)
	list := p.parseStmtList()
	rbrace := p.expect2(token.RBRACE)

	return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
}

// ---------------------------------------------------------------
// 表达式

func (p *parser) parseFuncTypeOrLit() ast.Expr {
	if p.trace {
		defer un(trace(p, "FuncTypeOrLit"))
	}

	typ := p.parseFuncType()
	if p.tok != token.LBRACE {
		// 函数类型仅
		return typ
	}

	p.exprLev++
	body := p.parseBody()
	p.exprLev--

	return &ast.FuncLit{Type: typ, Body: body}
}

// 解析操作数可以返回表达式或原始类型（包括数组
// 形式的类型[…]T.来电者必须核实结果。
// 
func (p *parser) parseOperand() ast.Expr {
	if p.trace {
		defer un(trace(p, "Operand"))
	}

	switch p.tok {
	case token.IDENT:
		x := p.parseIdent()
		return x

	case token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING:
		x := &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
		p.next()
		return x

	case token.LPAREN:
		lparen := p.pos
		p.next()
		p.exprLev++
		x := p.parseRhsOrType() // 类型可以用括号括起来：（某些类型）
		p.exprLev--
		rparen := p.expect(token.RPAREN)
		return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen}

	case token.FUNC:
		return p.parseFuncTypeOrLit()
	}

	if typ := p.tryIdentOrType(); typ != nil { // 不要使用尾部类型参数
		// 可以是复合文字或转换的类型
		_, isIdent := typ.(*ast.Ident)
		assert(!isIdent, "type cannot be identifier")
		return typ
	}

	// 我们有一个错误
	pos := p.pos
	p.errorExpected(pos, "operand")
	p.advance(stmtStart)
	return &ast.BadExpr{From: pos, To: p.pos}
}

func (p *parser) parseSelector(x ast.Expr) ast.Expr {
	if p.trace {
		defer un(trace(p, "Selector"))
	}

	sel := p.parseIdent()

	return &ast.SelectorExpr{X: x, Sel: sel}
}

func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr {
	if p.trace {
		defer un(trace(p, "TypeAssertion"))
	}

	lparen := p.expect(token.LPAREN)
	var typ ast.Expr
	if p.tok == token.TYPE {
		// 类型开关：typ==nil 
		p.next()
	} else {
		typ = p.parseType()
	}
	rparen := p.expect(token.RPAREN)

	return &ast.TypeAssertExpr{X: x, Type: typ, Lparen: lparen, Rparen: rparen}
}

func (p *parser) parseIndexOrSliceOrInstance(x ast.Expr) ast.Expr {
	if p.trace {
		defer un(trace(p, "parseIndexOrSliceOrInstance"))
	}

	lbrack := p.expect(token.LBRACK)
	if p.tok == token.RBRACK {
		// 不允许使用空索引、切片或索引表达式；
		// 接受它们的解析容差，但抱怨
		p.errorExpected(p.pos, "operand")
		rbrack := p.pos
		p.next()
		return &ast.IndexExpr{
			X:      x,
			Lbrack: lbrack,
			Index:  &ast.BadExpr{From: rbrack, To: rbrack},
			Rbrack: rbrack,
		}
	}
	p.exprLev++

	const N = 3 // 将3更改为2以禁用3索引切片
	var args []ast.Expr
	var index [N]ast.Expr
	var colons [N - 1]token.Pos
	var firstComma token.Pos
	if p.tok != token.COLON {
		// 我们不知道是否有索引表达式或类型实例化；
		// 所以即使我们看到一个（命名的）类型，我们也不会处于类型上下文中。
		index[0] = p.parseRhsOrType()
	}
	ncolons := 0
	switch p.tok {
	case token.COLON:
		// 切片表达式
		for p.tok == token.COLON && ncolons < len(colons) {
			colons[ncolons] = p.pos
			ncolons++
			p.next()
			if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
				index[ncolons] = p.parseRhs()
			}
		}
	case token.COMMA:
		firstComma = p.pos
		// 实例表达式
		args = append(args, index[0])
		for p.tok == token.COMMA {
			p.next()
			if p.tok != token.RBRACK && p.tok != token.EOF {
				args = append(args, p.parseType())
			}
		}
	}

	p.exprLev--
	rbrack := p.expect(token.RBRACK)

	if ncolons > 0 {
		// 切片表达式
		slice3 := false
		if ncolons == 2 {
			slice3 = true
			// 在这里检查第二和第三索引的存在，而不是在类型检查期间检查
			// 以防止错误程序通过gofmt（was问题7305）。
			if index[1] == nil {
				p.error(colons[0], "2nd index required in 3-index slice")
				index[1] = &ast.BadExpr{From: colons[0] + 1, To: colons[1]}
			}
			if index[2] == nil {
				p.error(colons[1], "3rd index required in 3-index slice")
				index[2] = &ast.BadExpr{From: colons[1] + 1, To: rbrack}
			}
		}
		return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: slice3, Rbrack: rbrack}
	}

	if len(args) == 0 {
		// 索引表达式
		return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
	}

	if !p.allowGenerics() {
		p.error(firstComma, "expected ']' or ':', found ','")
		return &ast.BadExpr{From: args[0].Pos(), To: args[len(args)-1].End()}
	}

	// 实例表达式
	return typeparams.PackIndexExpr(x, lbrack, args, rbrack)
}

func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
	if p.trace {
		defer un(trace(p, "CallOrConversion"))
	}

	lparen := p.expect(token.LPAREN)
	p.exprLev++
	var list []ast.Expr
	var ellipsis token.Pos
	for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
		list = append(list, p.parseRhsOrType()) // 内置可能需要一个类型：make（某些类型，…）
		if p.tok == token.ELLIPSIS {
			ellipsis = p.pos
			p.next()
		}
		if !p.atComma("argument list", token.RPAREN) {
			break
		}
		p.next()
	}
	p.exprLev--
	rparen := p.expectClosing(token.RPAREN, "argument list")

	return &ast.CallExpr{Fun: fun, Lparen: lparen, Args: list, Ellipsis: ellipsis, Rparen: rparen}
}

func (p *parser) parseValue() ast.Expr {
	if p.trace {
		defer un(trace(p, "Element"))
	}

	if p.tok == token.LBRACE {
		return p.parseLiteralValue(nil)
	}

	x := p.checkExpr(p.parseExpr())

	return x
}

func (p *parser) parseElement() ast.Expr {
	if p.trace {
		defer un(trace(p, "Element"))
	}

	x := p.parseValue()
	if p.tok == token.COLON {
		colon := p.pos
		p.next()
		x = &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseValue()}
	}

	return x
}

func (p *parser) parseElementList() (list []ast.Expr) {
	if p.trace {
		defer un(trace(p, "ElementList"))
	}

	for p.tok != token.RBRACE && p.tok != token.EOF {
		list = append(list, p.parseElement())
		if !p.atComma("composite literal", token.RBRACE) {
			break
		}
		p.next()
	}

	return
}

func (p *parser) parseLiteralValue(typ ast.Expr) ast.Expr {
	if p.trace {
		defer un(trace(p, "LiteralValue"))
	}

	lbrace := p.expect(token.LBRACE)
	var elts []ast.Expr
	p.exprLev++
	if p.tok != token.RBRACE {
		elts = p.parseElementList()
	}
	p.exprLev--
	rbrace := p.expectClosing(token.RBRACE, "composite literal")
	return &ast.CompositeLit{Type: typ, Lbrace: lbrace, Elts: elts, Rbrace: rbrace}
}

// checkExpr检查x是否是表达式（而不是类型）。
func (p *parser) checkExpr(x ast.Expr) ast.Expr {
	switch unparen(x).(type) {
	case *ast.BadExpr:
	case *ast.Ident:
	case *ast.BasicLit:
	case *ast.FuncLit:
	case *ast.CompositeLit:
	case *ast.ParenExpr:
		panic("unreachable")
	case *ast.SelectorExpr:
	case *ast.IndexExpr:
	case *ast.IndexListExpr:
	case *ast.SliceExpr:
	case *ast.TypeAssertExpr:
		// 如果t.Type==nil，则我们有一个
		// y.（Type）形式的类型断言，它只允许在类型开关表达式中使用。
		// 很难排除这些，但对于我们使用
		// 类型开关的情况。相反，要宽大一些，在
		// 型检查器中进行测试。
	case *ast.CallExpr:
	case *ast.StarExpr:
	case *ast.UnaryExpr:
	case *ast.BinaryExpr:
	default:
		// 所有其他节点都不是正确的表达式
		p.errorExpected(x.Pos(), "expression")
		x = &ast.BadExpr{From: x.Pos(), To: p.safePos(x.End())}
	}
	return x
}

// 如果x的形式是（T），UNPAEN返回UNPAEN（T），否则返回x。
func unparen(x ast.Expr) ast.Expr {
	if p, isParen := x.(*ast.ParenExpr); isParen {
		x = unparen(p.X)
	}
	return x
}

// checkExprOrType检查x是表达式还是类型
// （而不是像[…]这样的原始类型）T） 。
// 
func (p *parser) checkExprOrType(x ast.Expr) ast.Expr {
	switch t := unparen(x).(type) {
	case *ast.ParenExpr:
		panic("unreachable")
	case *ast.ArrayType:
		if len, isEllipsis := t.Len.(*ast.Ellipsis); isEllipsis {
			p.error(len.Pos(), "expected array length, found '...'")
			x = &ast.BadExpr{From: x.Pos(), To: p.safePos(x.End())}
		}
	}

	// 所有其他节点都是表达式或类型
	return x
}

func (p *parser) parsePrimaryExpr(x ast.Expr) ast.Expr {
	if p.trace {
		defer un(trace(p, "PrimaryExpr"))
	}

	if x == nil {
		x = p.parseOperand()
	}
	for {
		switch p.tok {
		case token.PERIOD:
			p.next()
			switch p.tok {
			case token.IDENT:
				x = p.parseSelector(p.checkExprOrType(x))
			case token.LPAREN:
				x = p.parseTypeAssertion(p.checkExpr(x))
			default:
				pos := p.pos
				p.errorExpected(pos, "selector or type assertion")
				// TODO（rFindley）检查令牌。下面的RBRACE是一个有针对性的修复
				// 错误恢复，足以使
				// 的x/tools测试通过为类型
				// 参数引入的新解析逻辑。一旦错误恢复被
				// 更普遍地重新考虑，就删除此选项。
				if p.tok != token.RBRACE {
					p.next() // 前进
				}
				sel := &ast.Ident{NamePos: pos, Name: "_"}
				x = &ast.SelectorExpr{X: x, Sel: sel}
			}
		case token.LBRACK:
			x = p.parseIndexOrSliceOrInstance(p.checkExpr(x))
		case token.LPAREN:
			x = p.parseCallOrConversion(p.checkExprOrType(x))
		case token.LBRACE:
			// 操作数可能返回了带括号的complit 
			// 类型；接受它，但如果我们有complit 
			t := unparen(x)
			// 请确定{'属于复合文字或块语句
			switch t.(type) {
			case *ast.BadExpr, *ast.Ident, *ast.SelectorExpr:
				if p.exprLev < 0 {
					return x
				}
				// x可能是复合文字类型
			case *ast.IndexExpr, *ast.IndexListExpr:
				if p.exprLev < 0 {
					return x
				}
				// x可能是复合文字类型
			case *ast.ArrayType, *ast.StructType, *ast.MapType:
				// x是复合文字类型
			default:
				return x
			}
			if t != x {
				p.error(t.Pos(), "cannot parenthesize type in composite literal")
				// 已经进行了，如果下一个标记是tok，则无需推进
			}
			x = p.parseLiteralValue(x)
		default:
			return x
		}
	}
}

func (p *parser) parseUnaryExpr() ast.Expr {
	if p.trace {
		defer un(trace(p, "UnaryExpr"))
	}

	switch p.tok {
	case token.ADD, token.SUB, token.NOT, token.XOR, token.AND:
		pos, op := p.pos, p.tok
		p.next()
		x := p.parseUnaryExpr()
		return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)}

	case token.ARROW:
		// 通道类型或接收表达式
		arrow := p.pos
		p.next()

		// 如果EN我们仍然不知道它是一个通道类型还是一个接收操作——我们只知道找到一元表达式的结尾。有两种情况：
		// 
		// /<-type=>（<-type）必须是通道类型
		// /<-expr=>（-expr）是从表达式
		// 
		// 接收的第一种情况，箭头必须与
		// /已解析的频道类型重新关联：
		// 
		// /-（chan type）=>（<-chan type）
		// /-（chan<-type）=>（<-chan type））

		x := p.parseUnaryExpr()

		// /确定哪种情况下我们有
		if typ, ok := x.(*ast.ChanType); ok {
			// /（<-type）

			dir := ast.SEND
			for ok && dir == ast.SEND {
				if typ.Dir == ast.RECV {
					p.errorExpected(typ.Arrow, "'chan'")
				}
				arrow, typ.Begin, typ.Arrow = typ.Arrow, arrow, arrow
				dir, typ.Dir = typ.Dir, ast.RECV
				typ, ok = typ.Value.(*ast.ChanType)
			}
			if dir == ast.SEND {
				p.errorExpected(arrow, "channel type")
			}

			return x
		}

		// /<-（expr）
		return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: p.checkExpr(x)}

	case token.MUL:
		// 指针类型或一元“*”表达式
		pos := p.pos
		p.next()
		x := p.parseUnaryExpr()
		return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)}
	}

	return p.parsePrimaryExpr(nil)
}

func (p *parser) tokPrec() (token.Token, int) {
	tok := p.tok
	if p.inRhs && tok == token.ASSIGN {
		tok = token.EQL
	}
	return tok, tok.Precedence()
}

// parseBinaryExpr解析（可能）二进制表达式。
// 如果x不是nil，则将其用作左操作数。
// 如果check为true，则检查操作数是否为有效表达式。
// 
// TODO（rfindley）：parseBinaryExpr已超载。考虑重构。
func (p *parser) parseBinaryExpr(x ast.Expr, prec1 int, check bool) ast.Expr {
	if p.trace {
		defer un(trace(p, "BinaryExpr"))
	}

	if x == nil {
		x = p.parseUnaryExpr()
	}
	for {
		op, oprec := p.tokPrec()
		if oprec < prec1 {
			return x
		}
		pos := p.expect(op)
		y := p.parseBinaryExpr(nil, oprec+1, check)
		if check {
			x = p.checkExpr(x)
			y = p.checkExpr(y)
		}
		x = &ast.BinaryExpr{X: x, OpPos: pos, Op: op, Y: y}
	}
}

// checkBinaryExpr检查尚未由
// parseBinaryExpr检查的二进制表达式，因为后者是用check=false调用的。
func (p *parser) checkBinaryExpr(x ast.Expr) {
	bx, ok := x.(*ast.BinaryExpr)
	if !ok {
		return
	}

	bx.X = p.checkExpr(bx.X)
	bx.Y = p.checkExpr(bx.Y)

	// parseBinaryExpr检查树中每个二进制表达式的x和y，因此我们
	// 从x开始遍历二进制表达式树。
	p.checkBinaryExpr(bx.X)
	p.checkBinaryExpr(bx.Y)
}

// 结果可能是一个类型，甚至是一个原始类型（[…]int）。调用方必须根据上下文检查结果（使用checkExpr或checkExprOrType）。
func (p *parser) parseExpr() ast.Expr {
	if p.trace {
		defer un(trace(p, "Expression"))
	}

	return p.parseBinaryExpr(nil, token.LowestPrec+1, true)
}

func (p *parser) parseRhs() ast.Expr {
	old := p.inRhs
	p.inRhs = true
	x := p.checkExpr(p.parseExpr())
	p.inRhs = old
	return x
}

func (p *parser) parseRhsOrType() ast.Expr {
	old := p.inRhs
	p.inRhs = true
	x := p.checkExprOrType(p.parseExpr())
	p.inRhs = old
	return x
}

// ----------------------------------------------------------------------------------------
// 语句

// parseSimpleStmt的解析模式。
const (
	basic = iota
	labelOk
	rangeOk
)

// parseSimpleStmt如果解析range子句的赋值
// （mode==rangeOk），则返回true作为第二个结果。返回的语句是一个
// 赋值，右边是
// 形式为“range x”的一元表达式。左侧不提供任何保证。
func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
	if p.trace {
		defer un(trace(p, "SimpleStmt"))
	}

	x := p.parseList(false)

	switch p.tok {
	case
		token.DEFINE, token.ASSIGN, token.ADD_ASSIGN,
		token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
		token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN,
		token.XOR_ASSIGN, token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN:
		// 赋值语句，可能是range子句的一部分
		pos, tok := p.pos, p.tok
		p.next()
		var y []ast.Expr
		isRange := false
		if mode == rangeOk && p.tok == token.RANGE && (tok == token.DEFINE || tok == token.ASSIGN) {
			pos := p.pos
			p.next()
			y = []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
			isRange = true
		} else {
			y = p.parseList(true)
		}
		as := &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}
		if tok == token.DEFINE {
			p.checkAssignStmt(as)
		}
		return as, isRange
	}

	if len(x) > 1 {
		p.errorExpected(x[0].Pos(), "1 expression")
		// 继续第一个表达式
	}

	switch p.tok {
	case token.COLON:
		// 带标签的语句
		colon := p.pos
		p.next()
		if label, isIdent := x[0].(*ast.Ident); mode == labelOk && isIdent {
			// Go spec:标签的作用域是函数
			// 的主体，在该函数中声明并排除任何嵌套
			// 函数的主体。
			stmt := &ast.LabeledStmt{Label: label, Colon: colon, Stmt: p.parseStmt()}
			return stmt, false
		}
		// 标签声明通常从x[0]开始。Pos（），但标签
		// 声明可能错误，因为该位置后面有标记（而
		// 在“：”之前）。如果未设置伪错误，则为该行报告的（唯一）错误
		// 是非法标签错误，而不是导致问题的“：”之前的标记
		// 。因此，使用（最新的）结肠
		// 错误报告位置。
		p.error(colon, "illegal label declaration")
		return &ast.BadStmt{From: x[0].Pos(), To: colon + 1}, false

	case token.ARROW:
		// send语句
		arrow := p.pos
		p.next()
		y := p.parseRhs()
		return &ast.SendStmt{Chan: x[0], Arrow: arrow, Value: y}, false

	case token.INC, token.DEC:
		// 递增或递减
		s := &ast.IncDecStmt{X: x[0], TokPos: p.pos, Tok: p.tok}
		p.next()
		return s, false
	}

	// 表达式
	return &ast.ExprStmt{X: x[0]}, false
}

func (p *parser) checkAssignStmt(as *ast.AssignStmt) {
	for _, x := range as.Lhs {
		if _, isIdent := x.(*ast.Ident); !isIdent {
			p.errorExpected(x.Pos(), "identifier on left side of :=")
		}
	}
}

func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
	x := p.parseRhsOrType() // 可能是一个转换：（某些类型）（x）
	if call, isCall := x.(*ast.CallExpr); isCall {
		return call
	}
	if _, isBad := x.(*ast.BadExpr); !isBad {
		// 只有在新的
		p.error(p.safePos(x.End()), fmt.Sprintf("function must be invoked in %s statement", callType))
	}
	return nil
}

func (p *parser) parseGoStmt() ast.Stmt {
	if p.trace {
		defer un(trace(p, "GoStmt"))
	}

	pos := p.expect(token.GO)
	call := p.parseCallExpr("go")
	p.expectSemi()
	if call == nil {
		return &ast.BadStmt{From: pos, To: pos + 2} // len（“go”）
	}

	return &ast.GoStmt{Go: pos, Call: call}
}

func (p *parser) parseDeferStmt() ast.Stmt {
	if p.trace {
		defer un(trace(p, "DeferStmt"))
	}

	pos := p.expect(token.DEFER)
	call := p.parseCallExpr("defer")
	p.expectSemi()
	if call == nil {
		return &ast.BadStmt{From: pos, To: pos + 5} // len（“延迟”）
	}

	return &ast.DeferStmt{Defer: pos, Call: call}
}

func (p *parser) parseReturnStmt() *ast.ReturnStmt {
	if p.trace {
		defer un(trace(p, "ReturnStmt"))
	}

	pos := p.pos
	p.expect(token.RETURN)
	var x []ast.Expr
	if p.tok != token.SEMICOLON && p.tok != token.RBRACE {
		x = p.parseList(true)
	}
	p.expectSemi()

	return &ast.ReturnStmt{Return: pos, Results: x}
}

func (p *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
	if p.trace {
		defer un(trace(p, "BranchStmt"))
	}

	pos := p.expect(tok)
	var label *ast.Ident
	if tok != token.FALLTHROUGH && p.tok == token.IDENT {
		label = p.parseIdent()
	}
	p.expectSemi()

	return &ast.BranchStmt{TokPos: pos, Tok: tok, Label: label}
}

func (p *parser) makeExpr(s ast.Stmt, want string) ast.Expr {
	if s == nil {
		return nil
	}
	if es, isExpr := s.(*ast.ExprStmt); isExpr {
		return p.checkExpr(es.X)
	}
	found := "simple statement"
	if _, isAss := s.(*ast.AssignStmt); isAss {
		found = "assignment"
	}
	p.error(s.Pos(), fmt.Sprintf("expected %s, found %s (missing parentheses around composite literal?)", want, found))
	return &ast.BadExpr{From: s.Pos(), To: p.safePos(s.End())}
}

// parseIfHeader是解析器的调整版本。头
// 在cmd/compile/internal/syntax/parser中。go，它的
// 经过了优化，可以更好地处理错误。
func (p *parser) parseIfHeader() (init ast.Stmt, cond ast.Expr) {
	if p.tok == token.LBRACE {
		p.error(p.pos, "missing condition in if statement")
		cond = &ast.BadExpr{From: p.pos, To: p.pos}
		return
	}
	// p.tok！=代币LBRACE 

	prevLev := p.exprLev
	p.exprLev = -1

	if p.tok != token.SEMICOLON {
		// 接受潜在变量声明，但抱怨
		if p.tok == token.VAR {
			p.next()
			p.error(p.pos, "var declaration not allowed in 'IF' initializer")
		}
		init, _ = p.parseSimpleStmt(basic)
	}

	var condStmt ast.Stmt
	var semi struct {
		pos token.Pos
		lit string // ”或“\n”；如果pos.IsValid（）
	}
	if p.tok != token.LBRACE {
		if p.tok == token.SEMICOLON {
			semi.pos = p.pos
			semi.lit = p.lit
			p.next()
		} else {
			p.expect(token.SEMICOLON)
		}
		if p.tok != token.LBRACE {
			condStmt, _ = p.parseSimpleStmt(basic)
		}
	} else {
		condStmt = init
		init = nil
	}

	if condStmt != nil {
		cond = p.makeExpr(condStmt, "boolean expression")
	} else if semi.pos.IsValid() {
		if semi.lit == "\n" {
			p.error(semi.pos, "unexpected newline, expecting { after if clause")
		} else {
			p.error(semi.pos, "missing condition in if statement")
		}
	}

	// 请确保我们有一个有效的AST 
	if cond == nil {
		cond = &ast.BadExpr{From: p.pos, To: p.pos}
	}

	p.exprLev = prevLev
	return
}

func (p *parser) parseIfStmt() *ast.IfStmt {
	if p.trace {
		defer un(trace(p, "IfStmt"))
	}

	pos := p.expect(token.IF)

	init, cond := p.parseIfHeader()
	body := p.parseBlockStmt()

	var else_ ast.Stmt
	if p.tok == token.ELSE {
		p.next()
		switch p.tok {
		case token.IF:
			else_ = p.parseIfStmt()
		case token.LBRACE:
			else_ = p.parseBlockStmt()
			p.expectSemi()
		default:
			p.errorExpected(p.pos, "if statement or block")
			else_ = &ast.BadStmt{From: p.pos, To: p.pos}
		}
	} else {
		p.expectSemi()
	}

	return &ast.IfStmt{If: pos, Init: init, Cond: cond, Body: body, Else: else_}
}

func (p *parser) parseTypeList() (list []ast.Expr) {
	if p.trace {
		defer un(trace(p, "TypeList"))
	}

	list = append(list, p.parseType())
	for p.tok == token.COMMA {
		p.next()
		list = append(list, p.parseType())
	}

	return
}

func (p *parser) parseCaseClause(typeSwitch bool) *ast.CaseClause {
	if p.trace {
		defer un(trace(p, "CaseClause"))
	}

	pos := p.pos
	var list []ast.Expr
	if p.tok == token.CASE {
		p.next()
		if typeSwitch {
			list = p.parseTypeList()
		} else {
			list = p.parseList(true)
		}
	} else {
		p.expect(token.DEFAULT)
	}

	colon := p.expect(token.COLON)
	body := p.parseStmtList()

	return &ast.CaseClause{Case: pos, List: list, Colon: colon, Body: body}
}

func isTypeSwitchAssert(x ast.Expr) bool {
	a, ok := x.(*ast.TypeAssertExpr)
	return ok && a.Type == nil
}

func (p *parser) isTypeSwitchGuard(s ast.Stmt) bool {
	switch t := s.(type) {
	case *ast.ExprStmt:
		// x.（type）
		return isTypeSwitchAssert(t.X)
	case *ast.AssignStmt:
		// v:=x.（type）
		if len(t.Lhs) == 1 && len(t.Rhs) == 1 && isTypeSwitchAssert(t.Rhs[0]) {
			switch t.Tok {
			case token.ASSIGN:
				// 允许v=x.（type）但抱怨
				p.error(t.TokPos, "expected ':=', found '='")
				fallthrough
			case token.DEFINE:
				return true
			}
		}
	}
	return false
}

func (p *parser) parseSwitchStmt() ast.Stmt {
	if p.trace {
		defer un(trace(p, "SwitchStmt"))
	}

	pos := p.expect(token.SWITCH)

	var s1, s2 ast.Stmt
	if p.tok != token.LBRACE {
		prevLev := p.exprLev
		p.exprLev = -1
		if p.tok != token.SEMICOLON {
			s2, _ = p.parseSimpleStmt(basic)
		}
		if p.tok == token.SEMICOLON {
			p.next()
			s1 = s2
			s2 = nil
			if p.tok != token.LBRACE {
				// 除了在初始SimpleStmt中声明的变量之外，TypeSwitchGuard还可以声明一个变量。
				// 引入额外作用域以避免重新声明错误：
				// 
				// 开关t:=0；t:=x（t）{…}ABCD224不能被访问，因为
				// 
				// 如果没有类型开关，s2必须是表达式。
				// 拥有额外的嵌套但为空的作用域不会影响它。
				s2, _ = p.parseSimpleStmt(basic)
			}
		}
		p.exprLev = prevLev
	}

	typeSwitch := p.isTypeSwitchGuard(s2)
	lbrace := p.expect(token.LBRACE)
	var list []ast.Stmt
	for p.tok == token.CASE || p.tok == token.DEFAULT {
		list = append(list, p.parseCaseClause(typeSwitch))
	}
	rbrace := p.expect(token.RBRACE)
	p.expectSemi()
	body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}

	if typeSwitch {
		return &ast.TypeSwitchStmt{Switch: pos, Init: s1, Assign: s2, Body: body}
	}

	return &ast.SwitchStmt{Switch: pos, Init: s1, Tag: p.makeExpr(s2, "switch expression"), Body: body}
}

func (p *parser) parseCommClause() *ast.CommClause {
	if p.trace {
		defer un(trace(p, "CommClause"))
	}

	pos := p.pos
	var comm ast.Stmt
	if p.tok == token.CASE {
		p.next()
		lhs := p.parseList(false)
		if p.tok == token.ARROW {
			// SendStmt 
			if len(lhs) > 1 {
				p.errorExpected(lhs[0].Pos(), "1 expression")
				// 继续第一个表达式
			}
			arrow := p.pos
			p.next()
			rhs := p.parseRhs()
			comm = &ast.SendStmt{Chan: lhs[0], Arrow: arrow, Value: rhs}
		} else {
			// RecvStmt 
			if tok := p.tok; tok == token.ASSIGN || tok == token.DEFINE {
				// RecvStmt带赋值
				if len(lhs) > 2 {
					p.errorExpected(lhs[0].Pos(), "1 or 2 expressions")
					// 继续前两个表达式
					lhs = lhs[0:2]
				}
				pos := p.pos
				p.next()
				rhs := p.parseRhs()
				as := &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
				if tok == token.DEFINE {
					p.checkAssignStmt(as)
				}
				comm = as
			} else {
				// lhs必须是单接收操作
				if len(lhs) > 1 {
					p.errorExpected(lhs[0].Pos(), "1 expression")
					// 继续第一个表达式
				}
				comm = &ast.ExprStmt{X: lhs[0]}
			}
		}
	} else {
		p.expect(token.DEFAULT)
	}

	colon := p.expect(token.COLON)
	body := p.parseStmtList()

	return &ast.CommClause{Case: pos, Comm: comm, Colon: colon, Body: body}
}

func (p *parser) parseSelectStmt() *ast.SelectStmt {
	if p.trace {
		defer un(trace(p, "SelectStmt"))
	}

	pos := p.expect(token.SELECT)
	lbrace := p.expect(token.LBRACE)
	var list []ast.Stmt
	for p.tok == token.CASE || p.tok == token.DEFAULT {
		list = append(list, p.parseCommClause())
	}
	rbrace := p.expect(token.RBRACE)
	p.expectSemi()
	body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}

	return &ast.SelectStmt{Select: pos, Body: body}
}

func (p *parser) parseForStmt() ast.Stmt {
	if p.trace {
		defer un(trace(p, "ForStmt"))
	}

	pos := p.expect(token.FOR)

	var s1, s2, s3 ast.Stmt
	var isRange bool
	if p.tok != token.LBRACE {
		prevLev := p.exprLev
		p.exprLev = -1
		if p.tok != token.SEMICOLON {
			if p.tok == token.RANGE {
				// “范围x”（赋值中的lhs）
				pos := p.pos
				p.next()
				y := []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
				s2 = &ast.AssignStmt{Rhs: y}
				isRange = true
			} else {
				s2, isRange = p.parseSimpleStmt(rangeOk)
			}
		}
		if !isRange && p.tok == token.SEMICOLON {
			p.next()
			s1 = s2
			s2 = nil
			if p.tok != token.SEMICOLON {
				s2, _ = p.parseSimpleStmt(basic)
			}
			p.expectSemi()
			if p.tok != token.LBRACE {
				s3, _ = p.parseSimpleStmt(basic)
			}
		}
		p.exprLev = prevLev
	}

	body := p.parseBlockStmt()
	p.expectSemi()

	if isRange {
		as := s2.(*ast.AssignStmt)
		// check lhs 
		var key, value ast.Expr
		switch len(as.Lhs) {
		case 0:
			// nothing to do 
		case 1:
			key = as.Lhs[0]
		case 2:
			key, value = as.Lhs[0], as.Lhs[1]
		default:
			p.errorExpected(as.Lhs[len(as.Lhs)-1].Pos(), "at most 2 expressions")
			return &ast.BadStmt{From: pos, To: p.safePos(body.End())}
		}
		// parseSimpleStmt返回了一个右侧，即
		// 是一个形式为“range x”的单元表达式
		x := as.Rhs[0].(*ast.UnaryExpr).X
		return &ast.RangeStmt{
			For:    pos,
			Key:    key,
			Value:  value,
			TokPos: as.TokPos,
			Tok:    as.Tok,
			X:      x,
			Body:   body,
		}
	}

	// 正则语句
	return &ast.ForStmt{
		For:  pos,
		Init: s1,
		Cond: p.makeExpr(s2, "boolean or range expression"),
		Post: s3,
		Body: body,
	}
}

func (p *parser) parseStmt() (s ast.Stmt) {
	if p.trace {
		defer un(trace(p, "Statement"))
	}

	switch p.tok {
	case token.CONST, token.TYPE, token.VAR:
		s = &ast.DeclStmt{Decl: p.parseDecl(stmtStart)}
	case
		// 可以启动表达式的标记
		token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // 操作数
		token.LBRACK, token.STRUCT, token.MAP, token.CHAN, token.INTERFACE, // 复合类型
		token.ADD, token.SUB, token.MUL, token.AND, token.XOR, token.ARROW, token.NOT: // 一元运算符
		s, _ = p.parseSimpleStmt(labelOk)
		// 由于需要向前看，带标签的语句是
		// 由parseSimpleStmt解析-不要在
		// 后面加分号
		if _, isLabeledStmt := s.(*ast.LabeledStmt); !isLabeledStmt {
			p.expectSemi()
		}
	case token.GO:
		s = p.parseGoStmt()
	case token.DEFER:
		s = p.parseDeferStmt()
	case token.RETURN:
		s = p.parseReturnStmt()
	case token.BREAK, token.CONTINUE, token.GOTO, token.FALLTHROUGH:
		s = p.parseBranchStmt(p.tok)
	case token.LBRACE:
		s = p.parseBlockStmt()
		p.expectSemi()
	case token.IF:
		s = p.parseIfStmt()
	case token.SWITCH:
		s = p.parseSwitchStmt()
	case token.SELECT:
		s = p.parseSelectStmt()
	case token.FOR:
		s = p.parseForStmt()
	case token.SEMICOLON:
		// 在有效的程序中有可能有一个隐式分号
		// 生成一个空语句吗？
		// （无论如何都要正确处理）
		s = &ast.EmptyStmt{Semicolon: p.pos, Implicit: p.lit == "\n"}
		p.next()
	case token.RBRACE:
		// 在结束“}”之前可以省略分号
		s = &ast.EmptyStmt{Semicolon: p.pos, Implicit: true}
	default:
		// 找不到任何语句
		pos := p.pos
		p.errorExpected(pos, "statement")
		p.advance(stmtStart)
		s = &ast.BadStmt{From: pos, To: p.pos}
	}

	return
}

// ---------------------------------------------------------------
// 声明

type parseSpecFunction func(doc *ast.CommentGroup, pos token.Pos, keyword token.Token, iota int) ast.Spec

func isValidImport(lit string) bool {
	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
	s, _ := strconv.Unquote(lit) // go/scanner返回合法字符串文字
	for _, r := range s {
		if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
			return false
		}
	}
	return s != ""
}

func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Token, _ int) ast.Spec {
	if p.trace {
		defer un(trace(p, "ImportSpec"))
	}

	var ident *ast.Ident
	switch p.tok {
	case token.PERIOD:
		ident = &ast.Ident{NamePos: p.pos, Name: "."}
		p.next()
	case token.IDENT:
		ident = p.parseIdent()
	}

	pos := p.pos
	var path string
	if p.tok == token.STRING {
		path = p.lit
		if !isValidImport(path) {
			p.error(pos, "invalid import path: "+path)
		}
		p.next()
	} else {
		p.expect(token.STRING) // 使用expect（）错误处理
	}
	p.expectSemi() // 访问p.linecomment前调用

	// 收集导入
	spec := &ast.ImportSpec{
		Doc:     doc,
		Name:    ident,
		Path:    &ast.BasicLit{ValuePos: pos, Kind: token.STRING, Value: path},
		Comment: p.lineComment,
	}
	p.imports = append(p.imports, spec)

	return spec
}

func (p *parser) parseValueSpec(doc *ast.CommentGroup, _ token.Pos, keyword token.Token, iota int) ast.Spec {
	if p.trace {
		defer un(trace(p, keyword.String()+"Spec"))
	}

	pos := p.pos
	idents := p.parseIdentList()
	typ := p.tryIdentOrType()
	var values []ast.Expr
	// 始终允许可选初始化以进行更宽容的解析
	if p.tok == token.ASSIGN {
		p.next()
		values = p.parseList(true)
	}
	p.expectSemi() // 访问p.linecomment前调用

	switch keyword {
	case token.VAR:
		if typ == nil && values == nil {
			p.error(pos, "missing variable type or initialization")
		}
	case token.CONST:
		if values == nil && (iota == 0 || typ != nil) {
			p.error(pos, "missing constant value")
		}
	}

	spec := &ast.ValueSpec{
		Doc:     doc,
		Names:   idents,
		Type:    typ,
		Values:  values,
		Comment: p.lineComment,
	}
	return spec
}

func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *ast.Ident, typ0 ast.Expr) {
	if p.trace {
		defer un(trace(p, "parseGenericType"))
	}

	list := p.parseParameterList(name0, typ0, token.RBRACK)
	closePos := p.expect(token.RBRACK)
	spec.TypeParams = &ast.FieldList{Opening: openPos, List: list, Closing: closePos}
	// 让类型检查器决定是否接受别名的类型参数：
	// 请参阅问题#46477。
	if p.tok == token.ASSIGN {
		// 类型别名
		spec.Assign = p.pos
		p.next()
	}
	spec.Type = p.parseType()
}

func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Token, _ int) ast.Spec {
	if p.trace {
		defer un(trace(p, "TypeSpec"))
	}

	ident := p.parseIdent()
	spec := &ast.TypeSpec{Doc: doc, Name: ident}

	if p.tok == token.LBRACK && p.allowGenerics() {
		lbrack := p.pos
		p.next()
		if p.tok == token.IDENT {
			// 我们可能有一个数组类型或类型参数列表。
			// 在这两种情况下，我们都希望得到一个表达式x（它可能只是一个名称，或者更复杂的表达式），我们可以进一步分析它。
			// 
			// 类型参数列表可能有一个以“[”开头的类型绑定，如：P[]E。在这种情况下，只需解析
			// 表达式就会导致错误：P[]无效。
			// 但由于索引或切片表达式从来都不是常量
			// 因此数组长度表达式无效，如果我们看到一个
			// “[”跟在一个名称后面，它必须是数组
			// 或切片约束的开头。只有当我们没有看到“[”时，我们
			// 才需要解析一个完整的表达式。

			// 索引或切片表达式从来都不是常量，因此
			// 数组长度表达式无效。因此，如果我们看到“[”以下名称
			// 我们可以安全地假设“[”name启动一个类型参数列表。
			var x ast.Expr = p.parseIdent()
			if p.tok != token.LBRACK {
				// 要解析以name开头的表达式，请展开
				// 我们将通过将名称
				// 传递到parser.expr，并将名称传递到parseryexpr.
				p.exprLev++
				lhs := p.parsePrimaryExpr(x)
				x = p.parseBinaryExpr(lhs, token.LowestPrec+1, false)
				p.exprLev--
			}

			// 分析案例
			var pname *ast.Ident // pname！=nil表示pname是类型参数名
			var ptype ast.Expr   // ptype！=nil表示ptype是类型参数类型；pname！=nil在本例中

			switch t := x.(type) {
			case *ast.Ident:
				// 除非我们看到“]”，否则我们处于类型参数列表的开头。
				if p.tok != token.RBRACK {
					// d.Name“[”Name…
					pname = t
					// no ptype 
				}
			case *ast.BinaryExpr:
				// 如果我们有一个形式为Name*T的表达式，并且T是一个（可能是带括号的
				// 类型文字，或者下一个标记是一个逗号，那么我们在类型参数列表的开头就是
				// d.Name”[“Name”*“T.Y 
				if name, _ := t.X.(*ast.Ident); name != nil {
					if t.Op == token.MUL && (isTypeLit(t.Y) || p.tok == token.COMMA) {
						// 将t转换为一元*t.Y 
						pname = name
						ptype = &ast.StarExpr{Star: t.OpPos, X: t.Y}
					}
				}
				if pname == nil {
					// 一个普通的二进制表达式。由于我们通过了check=false，我们必须检查它的操作数。
					p.checkBinaryExpr(t)
				}
			case *ast.CallExpr:
				// 如果我们有一个形式名称（T）的表达式，并且T是一个（可能是带括号的
				// 类型文字，或者下一个标记是逗号，那么在类型参数列表的开头就是
				// 了。
				if name, _ := t.Fun.(*ast.Ident); name != nil {
					if len(t.Args) == 1 && !t.Ellipsis.IsValid() && (isTypeLit(t.Args[0]) || p.tok == token.COMMA) {
						// d.Name“[“Name”（“t.ArgList[0]”）
						// d.Name”[“Name”（“t.ArgList[0]”）”，“
						pname = name
						ptype = t.Args[0]
					}
				}
			}

			if pname != nil {
				// d.Name”[“pname…
				// d.Name”[“pname ptype…
				p.parseGenericType(spec, lbrack, pname, ptype)
			} else {
				spec.Type = p.parseArrayType(lbrack, x)
			}
		} else {
			// 数组类型
			spec.Type = p.parseArrayType(lbrack, nil)
		}
	} else {
		// 无类型参数
		if p.tok == token.ASSIGN {
			// 类型别名
			spec.Assign = p.pos
			p.next()
		}
		spec.Type = p.parseType()
	}

	p.expectSemi() // 在访问p.linecomment 
	spec.Comment = p.lineComment

	return spec
}

// isTypeLit报告x是否为（可能带括号的）类型文字。
func isTypeLit(x ast.Expr) bool {
	switch x := x.(type) {
	case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
		return true
	case *ast.StarExpr:
		// /*T可能是指针解引用。如果T是一个类型文字，ABCFDG 
		return isTypeLit(x.X)
	case *ast.ParenExpr:
		return isTypeLit(x.X)
	}
	return false
}

func (p *parser) parseGenDecl(keyword token.Token, f parseSpecFunction) *ast.GenDecl {
	if p.trace {
		defer un(trace(p, "GenDecl("+keyword.String()+")"))
	}

	doc := p.leadComment
	pos := p.expect(keyword)
	var lparen, rparen token.Pos
	var list []ast.Spec
	if p.tok == token.LPAREN {
		lparen = p.pos
		p.next()
		for iota := 0; p.tok != token.RPAREN && p.tok != token.EOF; iota++ {
			list = append(list, f(p.leadComment, pos, keyword, iota))
		}
		rparen = p.expect(token.RPAREN)
		p.expectSemi()
	} else {
		list = append(list, f(nil, pos, keyword, 0))
	}

	return &ast.GenDecl{
		Doc:    doc,
		TokPos: pos,
		Tok:    keyword,
		Lparen: lparen,
		Specs:  list,
		Rparen: rparen,
	}
}

func (p *parser) parseFuncDecl() *ast.FuncDecl {
	if p.trace {
		defer un(trace(p, "FunctionDecl"))
	}

	doc := p.leadComment
	pos := p.expect(token.FUNC)

	var recv *ast.FieldList
	if p.tok == token.LPAREN {
		_, recv = p.parseParameters(false)
	}

	ident := p.parseIdent()

	tparams, params := p.parseParameters(true)
	if recv != nil && tparams != nil {
		// 方法声明没有类型参数。我们将它们解析为
		// 更好的错误消息和更好的错误恢复。
		p.error(tparams.Opening, "method must have no type parameters")
		tparams = nil
	}
	results := p.parseResult()

	var body *ast.BlockStmt
	switch p.tok {
	case token.LBRACE:
		body = p.parseBody()
		p.expectSemi()
	case token.SEMICOLON:
		p.next()
		if p.tok == token.LBRACE {
			// 开幕式{of function declaration on next line 
			p.error(p.pos, "unexpected semicolon or newline before {")
			body = p.parseBody()
			p.expectSemi()
		}
	default:
		p.expectSemi()
	}

	decl := &ast.FuncDecl{
		Doc:  doc,
		Recv: recv,
		Name: ident,
		Type: &ast.FuncType{
			Func:       pos,
			TypeParams: tparams,
			Params:     params,
			Results:    results,
		},
		Body: body,
	}
	return decl
}

func (p *parser) parseDecl(sync map[token.Token]bool) ast.Decl {
	if p.trace {
		defer un(trace(p, "Declaration"))
	}

	var f parseSpecFunction
	switch p.tok {
	case token.CONST, token.VAR:
		f = p.parseValueSpec

	case token.TYPE:
		f = p.parseTypeSpec

	case token.FUNC:
		return p.parseFuncDecl()

	default:
		pos := p.pos
		p.errorExpected(pos, "declaration")
		p.advance(sync)
		return &ast.BadDecl{From: pos, To: p.pos}
	}

	return p.parseGenDecl(p.tok, f)
}

// ---------------------------------------------------------------
// 源文件

func (p *parser) parseFile() *ast.File {
	if p.trace {
		defer un(trace(p, "File"))
	}

	// 如果扫描第一个标记时出错，请不要费心解析其余部分。
	// 可能根本不是Go源文件。
	if p.errors.Len() != 0 {
		return nil
	}

	// package子句
	doc := p.leadComment
	pos := p.expect(token.PACKAGE)
	// Go spec包装条款不是一种声明；
	// 包名不出现在任何作用域中。
	ident := p.parseIdent()
	if ident.Name == "_" && p.mode&DeclarationErrors != 0 {
		p.error(p.pos, "invalid package name _")
	}
	p.expectSemi()

	// 如果我们在解析package子句时出错，那么不要费心解析其余的。
	// 可能根本不是Go源文件。
	if p.errors.Len() != 0 {
		return nil
	}

	var decls []ast.Decl
	if p.mode&PackageClauseOnly == 0 {
		// 进口日期
		for p.tok == token.IMPORT {
			decls = append(decls, p.parseGenDecl(token.IMPORT, p.parseImportSpec))
		}

		if p.mode&ImportsOnly == 0 {
			// 包装体剩余部分
			for p.tok != token.EOF {
				decls = append(decls, p.parseDecl(declStart))
			}
		}
	}

	f := &ast.File{
		Doc:      doc,
		Package:  pos,
		Name:     ident,
		Decls:    decls,
		Imports:  p.imports,
		Comments: p.comments,
	}
	var declErr func(token.Pos, string)
	if p.mode&DeclarationErrors != 0 {
		declErr = p.error
	}
	if p.mode&SkipObjectResolution == 0 {
		resolveFile(f, p.file, declErr)
	}

	return f
}
